package com.urea.system.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.urea.system.config.MqttProviderConfig;
import com.urea.system.domain.Terminal;
import com.urea.system.domain.TerminalCommLog;
import com.urea.system.domain.TerminalNotice;
import com.urea.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 类描述: 硬件交互
 *
 * @author fangXu
 * @version 1.0
 * @date 2023/9/18 16:24
 */
@Service
public class HardwareServiceImpl implements IHardwareService {

    @Autowired
    private MqttProviderConfig providerClient;
    @Autowired
    private ITerminalCommLogService commLogService;
    @Autowired
    private ITerminalNoticeService noticeService;
    @Autowired
    private ITerminalService terminalService;
    @Value("${spring.mqtt.providerTopic}")
    private String topic;
    @Value("${spring.mqtt.providerTopicCode}")
    private String code;


    /**
     * 硬件配置指令
     *
     * @param price   单价
     * @param pulse   脉冲
     * @param solo   0表示单机模式、1表示远程模式
     * @param timeout 超时时间
     */
    @Override
    public void config(String price, String pulse, Integer solo, String timeout, String tNo) {
        JSONObject param = new JSONObject();
        JSONObject data = new JSONObject();
        String type = "config";
        param.put("op", type);
        data.put("price", price);
        data.put("pulse", pulse);
        data.put("timeout", timeout);
        data.put("solo", solo == 1 ? 0 : 1);
        param.put("da", data);
        String status = "1";
        try {
            providerClient.publish(1, false, topic.concat(tNo).concat(code), param.toJSONString());
        } catch (Exception e) {
            status = "0";
            saveNotice(tNo);
        } finally {
            saveCommLog(tNo, type, param.toJSONString(), null, status);
        }
    }

    /**
     * 硬件出货
     *
     * @param ser     跟踪序列号
     * @param userId  用户id
     * @param balance 金额
     * @param tNo
     */
    @Override
    public void run(String ser, String userId, BigDecimal balance, String tNo) {
        JSONObject param = new JSONObject();
        JSONObject data = new JSONObject();
        String type = "run";
        param.put("op", type);
        data.put("ser", ser);
        data.put("card", userId);
        data.put("balance", balance.intValue());
        param.put("da", data);
        String status = "1";
        try {
            providerClient.publish(1, false, topic.concat(tNo).concat(code), param.toJSONString());
        } catch (Exception e) {
            status = "0";
            saveNotice(tNo);
        } finally {
            saveCommLog(tNo, type, param.toJSONString(), ser, status);
        }
    }

    /**
     * 停止指令
     *
     * @param ser 跟踪序列号
     * @param uid 本次订单关联
     */
    @Override
    public void stop(String ser, String uid, String tNo) {
        JSONObject param = new JSONObject();
        JSONObject data = new JSONObject();
        String type = "stop";
        param.put("op", type);
        data.put("ser", ser);
        param.put("da", data);
        param.put("uid", uid);
        String status = "1";
        try {
            providerClient.publish(1, false, topic.concat(tNo).concat(code), param.toJSONString());
        } catch (Exception e) {
            status = "0";
            saveNotice(tNo);
        } finally {
            saveCommLog(tNo, type, param.toJSONString(), ser, status);
        }
    }

    /**
     * 计费确认
     *
     * @param ser 跟踪序列号
     * @param uid 本次订单关联
     * @param tNo
     */
    @Override
    public void confirm(String ser, String uid, String tNo) {
        JSONObject param = new JSONObject();
        JSONObject data = new JSONObject();
        String type = "confirm";
        param.put("op", type);
        data.put("ser", ser);
        param.put("da", data);
        param.put("uid", uid);
        String status = "1";
        try {
            providerClient.publish(1, false, topic.concat(tNo).concat(code), param.toJSONString());
        } catch (Exception e) {
            status = "0";
            saveNotice(tNo);
        } finally {
            saveCommLog(tNo, type, param.toJSONString(), ser, status);
        }
    }

    private void saveCommLog(String tNo, String type, String content, String orderNo, String status) {
        // 记录通信日志
        // 记录通信日志
        TerminalCommLog commLog = new TerminalCommLog();
        commLog.setTerminalNo(tNo);
        commLog.setCommType(type);
        commLog.setContent(content);
        commLog.setSerialNo(orderNo);
        commLog.setStatus(status);
        commLogService.save(commLog);
    }

    private void saveNotice(String terminalNo) {
        TerminalNotice notice = new TerminalNotice();
        Terminal one = terminalService.getOne(Wrappers.lambdaQuery(Terminal.class).eq(Terminal::getTerminalNo, terminalNo));
        notice.setTerminalId(one.getId());
        // 故障
        notice.setNoticeType(1);
        notice.setTerminalCapacity(one.getCurrentCapacity());
        notice.setNotice("指令发送失败");
        noticeService.save(notice);
    }
}
